﻿using System;
using CxExtension;
using UnityEngine.EventSystems;
#pragma warning disable 649

namespace UnityEngine.UI
{
	public class SliderIntOffsetBar : UIBehaviour
	{
		[SerializeField]
		private InputField mValueInputField;                      //
		[SerializeField]
		private Text mMaxValueText;                      //

		[SerializeField]
		private Button mReduceButton;                      //
		[SerializeField]
		private Slider mSlider;                      //
		[SerializeField]
		private Button mAddButton;                      //
		[SerializeField]
		private float mStep = 1;                      //

		[SerializeField]
		private float mInputMinValue = 1;                      //
		private float mValue;                      //
		private Func<float, string> mNumFormatFunc = NumFormat;                      //
		private Action<Transform,bool> mButtonDisableAction;                      //
		[SerializeField]
		private Slider.SliderEvent m_OnValueChanged = new Slider.SliderEvent();
		/// <summary>
		///   <para>Callback executed when the value of the slider is changed.</para>
		/// </summary>
		public Slider.SliderEvent onValueChanged
		{
			get
			{
				return this.m_OnValueChanged;
			}
			set
			{
				this.m_OnValueChanged = value;
			}
		}

		public void SetButtonDisableAction(Action<Transform,bool> v)
		{
			mButtonDisableAction = v;
		}

		private static string NumFormat(float value)
		{
			var str = string.Format("{0:N0}", value);
			return str;
		}


		protected override void Awake()
		{
			base.Awake();
			if (mSlider == null)
			{
				Debug.LogErrorFormat("Slider is Null");
			}

			if (mValueInputField == null)
			{
				Debug.LogErrorFormat("mValueInputField is Null");
			}

			if (mMaxValueText == null)
			{
				Debug.LogErrorFormat("Slider is Null");

				return;
			}
			mReduceButton.onClick.AddListener(OnReduceClick);
			mAddButton.onClick.AddListener(OnAddClick);
			mSlider.onValueChanged.AddListener(OnSliderValueChange);

			mValueInputField.onValueChanged.AddListener(OnInputValueChanged);
			mValueInputField.onEndEdit.AddListener(OnInputEnd);
		}

		private void OnValueChange(float value)
		{
			onValueChanged.Invoke(value);
		}


		private void OnInputValueChanged(string arg0)
		{
			mValueInputField.transform.parent.ForceRebuildLayoutImmediate();
		}

		private void OnAddClick()
		{
			ChangeCurrentValue(mStep);
		}

		private void OnReduceClick()
		{
			ChangeCurrentValue(-mStep);
		}

		private void OnInputEnd(string arg0)
		{
			float value = 0;
			if (float.TryParse(arg0, out value))
			{
			}
			value = Mathf.Clamp(value, mInputMinValue, mSlider.maxValue);
			if (EqualValue(value))
			{
				mValueInputField.text = value.ToString();
				return;
			}

			mValue = value;
			mSlider.value = value;

			OnValueChange(value);

		}

		public float Value
		{
			get
			{
				return mValue;
			}
		}

		public void ChangeCurrentValue(float offset)
		{
			var value = mValue + offset;
			SetCurrentValue(value);
		}

		public void SetSliderMinValue(float value)
		{
			mSlider.minValue = value;
		}
		public void SetMinValue(float value)
		{
			
		}
		public void SetInputMinValue(float value)
		{

		}

		public void SetCurrentValue(float value)
		{
			value = Mathf.Clamp(value, mInputMinValue, mSlider.maxValue);
			if (EqualValue(value))
			{
				return;
			}
			mSlider.value = value;
			CheckButtonEnable(value);
			mValueInputField.text = mNumFormatFunc(value);
			mValue = value;
		}

		private void CheckButtonEnable(float value)
		{
			var newActive = mSlider.maxValue > value;
			if (newActive != mAddButton.interactable)
			{
				mAddButton.interactable = newActive;

				if (mButtonDisableAction != null) mButtonDisableAction(mAddButton.transform,newActive);
			}

			newActive = mInputMinValue < value;
			if (newActive != mReduceButton.interactable)
			{
				mReduceButton.interactable = newActive;
				if (mButtonDisableAction != null) mButtonDisableAction(mReduceButton.transform,newActive);
			}
			
		}


		private void SetValueInternal(float value)
		{
			mValue = value;
		}

		public void SetStep(float v)
		{
			mStep = v;	
		}


		public void SetMaxValue(float value)
		{
			var intValue = Mathf.FloorToInt(value);
			mSlider.minValue = intValue == 1 ? 0 : 1;
			mSlider.maxValue = value;
			CheckButtonEnable(mValue);
			mMaxValueText.text = mNumFormatFunc(value);

		}

		public bool EqualValue(float value)
		{
			return MathUtil.Equal(value, mValue, 0.5f);
		}


		private void OnSliderValueChange(float arg0)
		{
			arg0 = Mathf.Clamp(arg0, mInputMinValue, mSlider.maxValue);
			if (EqualValue(arg0))
			{
				mSlider.value = arg0;
				return;
			}

			mValue = arg0;
			CheckButtonEnable(mValue);
			mValueInputField.text = mNumFormatFunc(arg0);

			OnValueChange(arg0);
		}
	}
}
